/**
 * @file   maps.h
 * @brief  map data
 * @encode UTF-8
 * @log    date        author      notes
 *         2021.09.03  Jimmy       first version
 */
#ifndef __MAPS_H_ 
#define __MAPS_H_ 

#include <vector>
#include <cstring>
#include <cmath>

#define MAP_MAX_WIDTH         (1000)
#define MAP_MAX_HEIGHT        (1000)
#define MAP_RESOLUTION        (0.05f)

#define N_PI                  (3.14159265f)
#define N_PI_2                (N_PI / 2.0f)

/* Opencv窗口坐标
 * (0, 0) +-------------->  x
 *        |
 *        |
 *        |
 *        |
 *        |
 *      y v
 */

/*
 *  世界坐标
 *
 *  ^ y
 *  |
 *  |
 *  |
 *  |
 *  +---------------->  x
 * (0, 0)
 */

/* 地图像素为全白 */
const uint8_t MAP_PIXEL_CLR      = 255;
/* 地图像素为全黑 */
const uint8_t MAP_PIXEL_OBSTACLE = 0;


typedef struct _MapParam
{
    int width;
    int height;
    float resolution;
    float xMin;
    float yMin;

    _MapParam()
    {
        width      = MAP_MAX_WIDTH;
        height     = MAP_MAX_HEIGHT;
        resolution = MAP_RESOLUTION;
        xMin       = -MAP_MAX_WIDTH  * MAP_RESOLUTION * 0.5f;
        yMin       = -MAP_MAX_HEIGHT * MAP_RESOLUTION * 0.5f;
    }

    _MapParam(int width_, int height_, float xMin_, float yMin_)
    {
        width      = width_;
        height     = height_;
        resolution = 0.5f;
        xMin       = xMin_;
        yMin       = yMin_;
    }
}MapParam;

typedef struct _MapData
{
    MapParam param;
    std::vector<uint8_t> map;

    _MapData()
    {
        map.resize(param.width * param.height, 127);
    }

    _MapData(uint8_t val)
    {
        map.resize(param.width * param.height, val);
    }

    _MapData(const _MapData & copy)
    {
        param = copy.param;
        map   = copy.map;
    }

    _MapData(MapParam param, uint8_t val)
    {
        param = param;
        map.resize(param.width * param.height, val);
    }

    ~_MapData()
    {
        map.clear();
    }

    inline int x2idx(float x) const
	{
		int tempX = static_cast<int>((x - param.xMin) / param.resolution);
		tempX = tempX < param.width - 1 ? tempX : param.width - 1;//防止溢出
		tempX = tempX > 0 ? tempX : 0;
		return tempX;
	}
	inline int y2idx(float y) const
	{
		int tempY = static_cast<int>((y - param.yMin) / param.resolution);
		tempY = tempY < param.height - 1 ? tempY : param.height - 1;//防止溢出
		tempY = tempY > 0 ? tempY : 0;
		return tempY;
	}
	inline float idx2x(const unsigned int cx) const { return param.xMin + (cx + 0.5f)*param.resolution; }
	inline float idx2y(const unsigned int cy) const { return param.yMin + (cy + 0.5f)*param.resolution; }
}MapData;

struct Point
{
    int x, y;

    Point()
    {
        x = y = 0;
    }

    Point(int x_, int y_)
    {
        x = x_;
        y = y_;
    }
};



#endif	/* __MAPS_H_ */